package com.zoho.daliansheng.service;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.zoho.daliansheng.common.U8SystemRecord;
import com.zoho.daliansheng.common.ZohoRecord;
import com.zoho.daliansheng.config.CRMPathConfig;
import com.zoho.daliansheng.config.CRMSqlQuery;
import com.zoho.daliansheng.config.DatasourceEnum;
import com.zoho.daliansheng.config.U8SystemPathConfig;
import com.zoho.daliansheng.dlcr.DlcrU8WebService;
import com.zoho.daliansheng.dlcr.DlcrU8WebServiceSoap;
import com.zoho.daliansheng.dlcr.QueryRetInfo;
import com.zoho.daliansheng.utils.CommonUtil;
import com.zoho.daliansheng.utils.CrmApiUtil;
import com.zoho.daliansheng.utils.getCrmFieldUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;

import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

@Slf4j
@Service
public class AcceptListBusinessServiceImpl implements AcceptListBusinessService {

    ZohoRecord zohoRecord;

    U8SystemRecord u8SystemRecord;

    U8SystemPathConfig u8SystemPathConfig;

    CRMPathConfig crmPathConfig;

    CRMSqlQuery crmSqlQuery;

    public AcceptListBusinessServiceImpl(ZohoRecord zohoRecord, U8SystemRecord u8SystemRecord, U8SystemPathConfig u8SystemPathConfig, CRMPathConfig crmPathConfig, CRMSqlQuery crmSqlQuery) {
        this.zohoRecord = zohoRecord;
        this.u8SystemRecord = u8SystemRecord;
        this.u8SystemPathConfig = u8SystemPathConfig;
        this.crmPathConfig = crmPathConfig;
        this.crmSqlQuery = crmSqlQuery;
    }

    @Override
    public void synAcceptBusinessList() {
        // 1 客户
        List<String> tempFieldList = getCrmFieldUtil.getAccountFieldList();
        List<JSONObject> accountData = CrmApiUtil.getModuleData(zohoRecord.getAccessToken(), crmPathConfig.getAccountModuleName(), tempFieldList);

        // 用户
        List<JSONObject> allUserData = CrmApiUtil.getAllUserData(zohoRecord.getAccessToken());

        /*
         * 2 同步ERP 商业汇票
         */
        try {
//            synU8Data( DatasourceEnum.GONG_CHANG.getWebServiceUrl(), DatasourceEnum.GONG_CHANG.getAccountCode(), DatasourceEnum.GONG_CHANG.getCompanyName(), accountData, allUserData);
            synU8Data(DatasourceEnum.SU_ZHOU.getWebServiceUrl(), DatasourceEnum.SU_ZHOU.getAccountCode(), DatasourceEnum.SU_ZHOU.getCompanyName(), accountData, allUserData);
            synU8Data(DatasourceEnum.CHANG_ZHOU.getWebServiceUrl(), DatasourceEnum.CHANG_ZHOU.getAccountCode(), DatasourceEnum.CHANG_ZHOU.getCompanyName(), accountData, allUserData);
            synU8Data(DatasourceEnum.DA_LIAN.getWebServiceUrl(), DatasourceEnum.DA_LIAN.getAccountCode(), DatasourceEnum.DA_LIAN.getCompanyName(), accountData, allUserData);
            synU8Data(DatasourceEnum.XIN_CAI_LIAO.getWebServiceUrl(), DatasourceEnum.XIN_CAI_LIAO.getAccountCode(), DatasourceEnum.XIN_CAI_LIAO.getCompanyName(), accountData, allUserData);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void synU8Data(String webServiceUrl, String accountCode, String companyName, List<JSONObject> accountData, List<JSONObject> allUserData) throws MalformedURLException {

        log.info("同步【" + companyName + "】");

        String synModuleName = crmPathConfig.getAcceptListModuleName(); // 要同步的模块名称
        String businessModuleName = crmPathConfig.getBusinessModuleName(); // 最大版本号 模块名称

        // 1 模块最大版本号
        Map<String, String> map = CrmApiUtil.getMaxVersion(zohoRecord.getAccessToken(), businessModuleName, accountCode);
        String versionCrmId = map.get("id");
        int maxVersion = Integer.parseInt(map.get("maxVersion"));
        log.info("maxVersion={}", maxVersion);

        // 2 获取ERP数据
        DlcrU8WebService webService = new DlcrU8WebService(new URL(webServiceUrl));
        DlcrU8WebServiceSoap api = webService.getDlcrU8WebServiceSoap();
        QueryRetInfo queryRetInfo = api.queryRpNoteHeadByVersion(maxVersion);
        int queryMaxVersion = queryRetInfo.getMaxVersion();
        JSONArray jsonArray = JSONArray.parseArray(queryRetInfo.getJson());
        if (jsonArray.size() > 0) {
            // 3 比较数据
            List<JSONObject> insertList = new ArrayList<>();
            List<JSONObject> updateList = new ArrayList<>();
            List<String> deleteList = new ArrayList<>();
            List<JSONObject> batchCurrentStock = jsonArray.toJavaList(JSONObject.class);

            if (maxVersion == -1) {
                for (JSONObject erpData : batchCurrentStock) {
                    String cdigest = erpData.getString("cdigest"); // 票据摘要
                    if (StringUtils.isNotBlank(cdigest) && cdigest.contains("二次录入")) {
                        continue;
                    }
                    insertList.add(erpData);
                }
            } else {
                //log.info("batchCurrentStock={}", JSONObject.toJSONString(batchCurrentStock));
                for (JSONObject erpData : batchCurrentStock) {
                    // sys_change_operation 该字段非常关键,记录了记录的变动类型,I=Insert、U=Update、D=Delete
                    String operation = erpData.getString("sys_change_operation");
                    String cvouchid = erpData.getString("cvouchid"); // 票据编号
                    String cdigest = erpData.getString("cdigest"); // 票据摘要
                    if (StringUtils.isNotBlank(cdigest) && cdigest.contains("二次录入")) {
                        continue;
                    }
                    // 带英文的括号，就不同步
                    if (!operation.equals("D") && (StringUtils.isBlank(cvouchid) || cvouchid.contains("(") || cvouchid.contains(")"))) {
                        continue;
                    }
                    switch (operation) {
                        case "I":
                            insertList.add(erpData);
                            break;
                        case "U": {
                           String selectQuery = crmSqlQuery.getAcceptListByERP(cvouchid, companyName, "商业汇票");
                            List<JSONObject> searchList = CrmApiUtil.COQLQuery(zohoRecord.getAccessToken(), selectQuery);
                            if (searchList.size() > 0) {
                                JSONObject jsonObject = searchList.get(0);
                                String crmId = jsonObject.getString("id");
                                erpData.put("crmId", crmId);
                                updateList.add(erpData);
                            }
                            break;
                        }
                        case "D": {
                            //log.info("收款单商业汇票明细删除数据：{}", erpData.toJSONString());
                            String pk_id = erpData.getString("pk_id"); // pk_id
                            String pkId_searchUrl = "((pk_id:equals:" + pk_id + ")and(AffiliatedCompany:equals:" + companyName + "))";
                            List<JSONObject> searchList = CrmApiUtil.getModuleDataBySearch(zohoRecord.getAccessToken(), crmPathConfig.getAcceptListSearchUrl() + pkId_searchUrl);
                            //log.info("收款单商业汇票明细searchList：{}", JSONObject.toJSONString(searchList));
                            if (searchList.size() > 0) {
                                JSONObject jsonObject = searchList.get(0);
                                String crmId = jsonObject.getString("id");
                                deleteList.add(crmId);
                            }
                            break;
                        }
                    }
                }
            }

            // 4 字段映射
            List<JSONObject> crm_insertList = getCrmMappingData(insertList, companyName, accountData, allUserData);
            List<JSONObject> crm_updateList = getCrmMappingData(updateList, companyName, accountData, allUserData);
            System.out.println("crm_insertList.size() = " + crm_insertList.size());
            System.out.println("crm_updateList.size() = " + crm_updateList.size());
            System.out.println("deleteList.size() = " + deleteList.size());

            //log.info("crm_insertList={}", JSONObject.toJSONString(crm_insertList));
            //log.info("crm_updateList={}", JSONObject.toJSONString(crm_updateList));
            //log.info("deleteList={}", JSONObject.toJSONString(deleteList));

            // 5 批量操作
            CrmApiUtil.batchInsertDataByList(zohoRecord.getAccessToken(), crm_insertList, synModuleName);

            // 修改
            CrmApiUtil.batchUpdateDataByList(zohoRecord.getAccessToken(), crm_updateList, synModuleName);

            if (deleteList.size() > 0) {
                CrmApiUtil.batchDeleteModelData(zohoRecord.getAccessToken(), synModuleName, deleteList);
            }

            // 6 最大版本号回传
            if (queryMaxVersion != maxVersion) {
                CrmApiUtil.saveMaxVersion(zohoRecord.getAccessToken(), versionCrmId, queryMaxVersion, crmPathConfig.getMaxVersionModuleName());
            }
        }
    }

    private List<JSONObject> getCrmMappingData(List<JSONObject> erpList, String companyName, List<JSONObject> accountData, List<JSONObject> allUserData) {
        List<JSONObject> list = new ArrayList<>();

        for (JSONObject erpData : erpList) {
            JSONObject crmData = new JSONObject();
            String crmId = erpData.getString("crmId");
            if (StringUtils.isNotBlank(crmId)) {
                crmData.put("id", crmId);
            }

            crmData.put("ERP", erpData.getString("cvouchid")); // ERP收款单编号
            crmData.put("pk_id", erpData.getString("pk_id")); // pk_id
            crmData.put("AffiliatedCompany", companyName); // 所属公司
            crmData.put("order_type", "商业汇票"); // // 收款单类型
            String dreceiptdate = erpData.getString("dreceiptdate");
            if (StringUtils.isNotBlank(dreceiptdate)) {
                crmData.put("date", dreceiptdate.substring(0, 10)); // 日期（收到日期）
            }

            String dsigndate = erpData.getString("dsigndate");
            if (StringUtils.isNotBlank(dsigndate)) {
                crmData.put("Ticket_date", dsigndate.substring(0, 10)); // 出票日期
            }
            crmData.put("amount", CommonUtil.formatBigDecimal(erpData.getBigDecimal("iamount"), 2)); // 金额
            crmData.put("department", erpData.getString("cdepname")); // 部门
            crmData.put("account_bank", erpData.getString("csuperbank")); // 客户银行
            crmData.put("pay_bank", erpData.getString("cbank")); // 付款人银行（承兑）
            crmData.put("drawer", erpData.getString("cdwname")); // 出票人

            String dexpiredate = erpData.getString("dexpiredate");
            if (StringUtils.isNotBlank(dexpiredate)) {
                crmData.put("bill_expiration_date", dexpiredate.substring(0, 10)); // 到期日
            }
            crmData.put("encyType", erpData.getString("cexch_name")); // 币种
            crmData.put("Settlement_method", erpData.getString("csettlename")); // 结算方式（票据类型）
            crmData.put("rate", erpData.getString("nfrat")); // 汇率


            String cdwcode = erpData.getString("cdwcode"); // 客户编码
            if (StringUtils.isNotBlank(cdwcode)) {
                List<JSONObject> erp_account_num = accountData.stream().filter(object ->
                        Objects.nonNull(object.getString("ERP_account_num")) &&
                                object.getString("ERP_account_num").equals(cdwcode) &&
                                (Objects.nonNull(object.getString("KHCompany")) && object.getString("KHCompany").equals(companyName))
                ).collect(Collectors.toList());
                if (erp_account_num.size() > 0) {
                    JSONObject jsonObject = new JSONObject();
                    jsonObject.put("id", erp_account_num.get(0).getString("id"));
                    crmData.put("account_name", jsonObject); // 客户(出票人)
                }
            }
            String personCode = erpData.getString("cperson");
            JSONObject crmUserCodeByCompany = CrmApiUtil.getCRMUserCodeByCompany(allUserData, personCode, companyName);
            if (Objects.nonNull(crmUserCodeByCompany)) {
                crmData.put("Salesman", crmUserCodeByCompany); // 业务员
            }

            if (companyName.equals(DatasourceEnum.SU_ZHOU.getCompanyName())) {
                crmData.put("Ticket_bank_type", erpData.getString("cDefine9")); // 出票行类型
                crmData.put("zhuli", erpData.getString("cDefine1")); // 助理
            } else if (companyName.equals(DatasourceEnum.CHANG_ZHOU.getCompanyName())) {
                crmData.put("Ticket_bank_type", erpData.getString("chdefine26")); // 出票行类型
                crmData.put("zhuli", erpData.getString("chdefine23")); // 助理
            } else if (companyName.equals(DatasourceEnum.DA_LIAN.getCompanyName())) {
                crmData.put("Ticket_bank_type", erpData.getString("chdefine30")); // 出票行类型
                crmData.put("zhuli", erpData.getString("chdefine26")); // 助理
            } else if (companyName.equals(DatasourceEnum.XIN_CAI_LIAO.getCompanyName())) {
                crmData.put("Ticket_bank_type", erpData.getString("chdefine30")); // 出票行类型
                crmData.put("zhuli", erpData.getString("chdefine26")); // 助理
            }
            list.add(crmData);
        }
        return list;
    }
}

